/**
 * 1.斗地主全部的牌型：
单牌：任意一张单牌（3 < 4 <… < K< A < 2 < 小王<大王）。

对牌：任意两张点数相同的牌(88)。

三张：  任意三张点数相同的牌，如888。

炸弹：  四张点数相同的牌，如：7777。

火箭：  即双王（大王和小王），最大的牌，这个其实也可以归类到炸弹中去。

三带一：点数相同的三张牌+一张单牌。如：333+6 。

三带二：点数相同的三张牌+一对牌。如 444+99。
四带二：点数相同的四张牌+二张单牌，或者一对牌如4444+3+8 或 4444+33

四带四：点数相同的四张牌+二个对牌，如4444＋55＋77
单顺：   任意五张或五张以上点数相连的牌，如：45678或78910JQK。不包括 2和双王。　
双顺：   三对或更多的连续对牌，如：334455、7788991010JJ。不包括 2 点和双王。　　
飞机：   二个或更多的连续三张牌，如：333444 、555666777888。不包括 2 点和双王。　
飞机带翅膀（单牌）：　　三顺＋同数量的单牌，如：444555+79 

飞机带翅膀（对牌）：　　三顺＋同数量的对牌，如：333444555+7799JJ


(1)首先判断是不是火箭,判断list的长度为2，并且二张牌都是王就OK了，但是火箭，是可以归类到炸弹中。


(2)判断牌型为：单牌（c1），对子（c2），3不带（c3），4个一样炸弹（c4），三带一（c31）----共5种。
如果牌数少于5张，并且第一张和最后一张牌值相同，也就是所有的牌都相同，则根据牌数数目为1，2，3，4分别返回c1，c2，c3，c4。
如果牌数为4张，并且第一张和第三张牌值相同，或者第二张和第四张牌值相同，那么则返回c31。


(3)判断牌型为：c32,//3带2，c411,//4带2个单，或者一对，c422,//4带2对，c123,//连子，c1122,//连队，c111222,//飞机，c11122234,//飞机带单排，c1112223344,//飞机带对子。

先定义一个List a[4]，其中a[0]的值为list中重复一次(单张牌)的牌，a[1]的值为list中重复二次(对牌)的牌，a[2]的值为list中重复三次(三张)的牌，a[3]的值为list中重复四次(炸弹)的牌。
如果牌数大于等于5张，

c32(点数相同的三张牌+一对牌。如 444+99):
length（牌总数）为5  &&  a[2]. size()== 1 && a[1].size() == 1

c411(点数相同的四张牌+二张单牌，或者一对牌如4444+3+8 或 4444+33):
length（牌总数）为6  &&  a[3]. size()== 1

c422(点数相同的四张牌+二个对牌，如4444＋55＋77):
 length（牌总数）为8  &&  a[3]. size()== 1 && a[1].size() == 2

c123(任意五张或五张以上点数相连的牌，如：45678或78910JQK。不包括 2和双王)
牌值不包括双王和2  && a[0].size() == len   &&  （第一张牌值  - 最后一张牌值）== (length-1)

c1122(三对或更多的连续对牌，如：334455、7788991010JJ。不包括 2 点和双王)：
length / 2 >= 3   &&  length%2 == 0 && a[1].size() == length/ 2  &&  （第一张牌值  - 最后一张牌值）== (length/2-1)

c111222(二个或更多的连续三张牌，如：333444 、555666777888。不包括 2 点和双王):
a[2].size() == length/ 3   &&  (length% 3 == 0)  && （第一张牌值  - 最后一张牌值）== (length/3-1)

c11122234(三顺＋同数量的单牌，如：444555+79):
a[2].size() >= 2   &&   a[2].size() == length/ 4   && （a[2]的最后一个数 - a[2]的第一个数） == （length/ 4 - 1）

c1112223344（三顺＋同数量的对牌，如：333444555+7799JJ）：
a[2].size() >= 2  &&  a[2].size()  == length/ 5  &&  （a[2]的最后一个数 - a[2]的第一个数） == （length/ 5 - 1）
 */
module ChessType {
    export var cboom = "cboom";//单牌。
    export var c1 = "c1";//单牌。
    export var c2 = "c2";//对子。
    export var c3 = "c3";//3不带。
    export var c4 = "c4";//炸弹。
    export var c31 = "c31";//3带1。
    export var c32 = "c32";//3带2。
    export var c411 = "c411";//4带2个单，或者一对
    export var c422 = "c422";//4带2对
    export var c123 = "c123";//连子。
    export var c1122 = "c1122";//连队。
    export var c111222 = "c111222";//飞机。
    export var c11122234 = "c11122234";//飞机带单排.
    export var c1112223344 = "c1112223344";//飞机带对子.
    export var pass = "pass";//过牌
    export var cerror = "cerror";//不是任何牌型

    export function getType(upChess: Array<Poker_DDZ>) {
        let len = upChess.length;
        if (len == 0) {
            return pass;
        }
        if (len < 5) {
            if (isDan(upChess)) {
                return c1;
            } else if (isDuiZi(upChess)) {
                return c2;
            } else if (isSanBuDai(upChess)) {
                return c3;
            } else if (isZhaDan(upChess)) {
                return c4;
            } else if (isSanDaiYi(upChess)) {
                return c31;
            } else if (isDuiWang(upChess)) {
                return cboom;
            }
        } else if (len >= 5) {
            if (isShunZi(upChess)) {
                return c123;
            } else if (isLianDui(upChess)) {
                return c1122;
            } else if (isSanDaiEr(upChess)) {
                return c32;
            } else if (isDuoFeiJiBuDai(upChess)) {
                return c111222
            } else if (isDuoFeiJiDaiDan(upChess)) {
                return c11122234
            } else if (isDuoFeiJiDaiShuang(upChess)) {
                return c1112223344
            } else if (isSiDaiEr(upChess)) {
                return c411;
            } else if (isSiDaiErDui(upChess)) {
                return c422;
            }
        }
        return cerror;
    }

    //c1 判断牌是否为单
    export function isDan(upChess: Array<Poker_DDZ>): boolean {
        // 默认不是单
        let flag = false;
        if (upChess.length == 1) {
            flag = true;
        }
        return flag;
    }

    //c2 判断牌是否为对子
    export function isDuiZi(upChess: Array<Poker_DDZ>): boolean {
        // 默认不是对子
        let flag = false;
        if (upChess.length == 2) {
            if (upChess[0].value == upChess[1].value) {
                flag = true;
            }
        }
        return flag;
    }

    //c3 判断牌是否为3不带
    export function isSanBuDai(upChess: Array<Poker_DDZ>): boolean {
        // 默认不是3不带
        let flag = false;
        if (upChess.length == 3) {
            if (upChess[0].value == upChess[upChess.length - 1].value) {
                flag = true;
            }
        }
        return flag;
    }

    //c4 判断牌是否为炸弹
    export function isZhaDan(upChess: Array<Poker_DDZ>): boolean {
        // 默认不是炸弹
        let flag = false;
        if (upChess.length == 4) {
            if (upChess[0].value == upChess[upChess.length - 1].value) {
                flag = true;
            }
            return flag;
        }
    }

    //c31 判断牌是否为3带1 <<<再此之前请先判断是否为炸弹>>>
    export function isSanDaiYi(upChess: Array<Poker_DDZ>): boolean {
        let flag = false;
        // 默认不是3带1
        if (upChess.length == 4) {
            if ((upChess[0].value == upChess[2].value || upChess[1].value == upChess[3].value)) {
                flag = true;
            }
        }
        return flag;
    }
    // 判断牌是否为王炸
    export function isDuiWang(upChess: Array<Poker_DDZ>): boolean {
        // 默认不是对王
        let flag = false;
        if (upChess.length == 2) {
            if ((upChess[0].value + upChess[1].value) == 29) {
                flag = true;
            }
        }
        return flag;
    }
    /*
    以下为复杂牌型先拆分
    */
    //c123     例:3456789....不包括 2 点和双王
    export function isShunZi(upChess: Array<Poker_DDZ>): boolean {
        // if (upChess.length < 5) {//前面已经判断大于5才会进来
        //     return false;
        // }
        for (let i in upChess) {
            if (upChess[i].value == 13 || upChess[i].value == 14 || upChess[i].value == 15) {
                return false;
            }
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        //必须全是单牌且是连续的
        if (list[0].length == upChess.length && (upChess[0].value - upChess[upChess.length - 1].value) == (upChess.length - 1)) {
            return true
        }
        return false;
    }

    //c1122(三对或更多的连续对牌，如：334455、7788991010JJ。不包括 2 点和双王)：
    export function isLianDui(upChess: Array<Poker_DDZ>): boolean {
        if (upChess.length < 6 || upChess.length % 2 != 0) {
            return false;
        }
        for (let i in upChess) {
            if (upChess[i].value == 13 || upChess[i].value == 14 || upChess[i].value == 15) {
                return false;
            }
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        //必须全是对子 并且是连续的
        if (list[1].length == upChess.length / 2 && (upChess[0].value - upChess[upChess.length - 1].value) == (upChess.length / 2 - 1)) {
            return true;
        }
        return false;
    }
    //c32       例:AAA 33
    export function isSanDaiEr(upChess: Array<Poker_DDZ>): boolean {
        if (upChess.length != 5) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        if (list[2].length == 1 && list[1].length == 1) {
            return true
        }
        return false;
    }
    //c411     例:AAAA 34
    export function isSiDaiEr(upChess: Array<Poker_DDZ>): boolean {
        if (upChess.length != 6) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        if (list[3].length == 1) {
            return true
        }
        return false;
    }
    // c422   例:AAAA 3344
    export function isSiDaiErDui(upChess: Array<Poker_DDZ>): boolean {
        if (upChess.length != 8) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        if (list[3].length == 1 && list[1].length == 2) {
            return true
        }
        return false;
    }
    //c111222 多飞机不带 例：333444 、555666777888。多飞机部分不可包含2飞机
    export function isDuoFeiJiBuDai(upChess: Array<Poker_DDZ>): boolean {
        if (upChess.length < 6 && upChess.length % 3 != 0) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        //多飞机部分不可包含2飞机
        for (let i in list[2]) {
            if (list[2][i] == 13) {
                return false;
            }
        }
        //每3张牌必须组成飞机，并且飞机是连续的
        if (list[2].length == upChess.length / 3 && (upChess[0].value - upChess[upChess.length - 1].value) == (upChess.length / 3 - 1)) {
            return true;
        }
        return false;
    }
    //c11122234(多飞机带单，如：444555+79)://多飞机部分不可包含2飞机
    export function isDuoFeiJiDaiDan(upChess: Array<Poker_DDZ>) {
        if (upChess.length < 8 && upChess.length % 4 != 0) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        //多飞机部分不可包含2飞机
        for (let i in list[2]) {
            if (list[2][i] == 13) {
                return false;
            }
        }
        //每4张牌里必须有一个飞机，并且飞机必须是连续的
        if (list[2].length == upChess.length / 4 && (list[2][list[2].length - 1] - list[2][0]) == (upChess.length / 4 - 1)) {
            return true;
        }
        return false;
    }
    //c1112223344 多飞机带双333444555+7799JJ //多飞机部分不可包含2飞机
    export function isDuoFeiJiDaiShuang(upChess: Array<Poker_DDZ>) {
        if (upChess.length < 10 && upChess.length % 5 != 0) {
            return false;
        }
        let list: Array<Array<any>> = ChessType.chessSplice(upChess)
        //多飞机部分不可包含2飞机
        for (let i in list[2]) {
            if (list[2][i] == 13) {
                return false;
            }
        }
        //每5张牌必须有飞机和对子，并且飞机是连续的
        if (list[2].length == upChess.length / 5 && list[1].length == upChess.length / 5 && (list[2][list[2].length - 1] - list[2][0] == (upChess.length / 5 - 1))) {
            return true;
        }
        return false;
    }

    //复杂牌型拆分
    export function chessSplice(upChess: Array<Poker_DDZ>): Array<Array<any>> {
        //先统计每种牌出现多少次
        let obj = {};
        for (let i in upChess) {
            let val = upChess[i].value;
            if (Global.isNotEmpty(obj[val + ""])) {
                obj[val + ""] += 1;
            } else {
                obj[val + ""] = 1;
            }
        }
        let flag = false;
        //再按出现次数装入list对应的位置<下标 0 装单牌，1装对子，2装飞机，3装炸弹>
        let list: Array<Array<any>> = [[], [], [], []];
        for (let i in obj) {
            list[obj[i] - 1].push(i);
        }
        return list;
    }
}
